package com.nuonuo.nuo_xp;

/**
 * @author glsite.com
 * @version $Rev$
 * @des ${TODO}
 * @updateAuthor $Author$
 * @updateDes ${TODO}
 */


import android.util.Base64;
import android.util.Log;
import javax.crypto.Mac;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;

/**
 * Hook通杀HMAC
 * hook类
 * javax.crypto.spec.SecretKeySpec
 *javax.crypto.Mac
 */
public class HOOK_HMAC implements IXposedHookLoadPackage {
    private String log_d_tag="XP";
    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
        Log.d(log_d_tag,"注入成功...");
        Log.d(log_d_tag,"***HMAC算法***");
        Log.d(log_d_tag,"HOOK_class:javax.crypto.spec.SecretKeySpec");
        Log.d(log_d_tag,"HOOK_class:javax.crypto.Mac");
        Log.d(log_d_tag,"活动APP包名:"+loadPackageParam.packageName);
        //hmac 加密密钥和aes des 是同一个类方法 此处 可以不用写
        //Hook 密钥 （DES MAC AES 3DES）
        //构造函数hookAllConstructors有重载
        /*XposedBridge.hookAllConstructors(XposedHelpers.findClass("javax.crypto.spec.SecretKeySpec",
                loadPackageParam.classLoader),  new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                byte[] screKey = (byte[]) param.args[0];//第一个必为密钥
                Integer offset = 0;
                Integer size = 0;
                String algorithm = "";
                if (param.args.length!=2){
                    offset = (Integer) param.args[1];
                    size = (Integer) param.args[2];
                    algorithm = (String) param.args[3];
                }else {
                    size = screKey.length;
                    algorithm = (String) param.args[1];
                }
                byte[] keyByte = new byte[size];
                System.arraycopy(screKey,offset,keyByte,0,size);
                String data = new String(keyByte);
                String dataHex = Utils.byteToHexString(keyByte);
                String dataBase64 = Base64.encodeToString(keyByte,0);
                Log.d(log_d_tag,"-");
                Log.d(log_d_tag,"-");
                Log.d(log_d_tag,"====================================HOOK开始============================================");
                Log.d(log_d_tag,"====================================Class_HMAC============================================");
                Log.d(log_d_tag,algorithm+"_screKey_Data:"+data);
                Log.d(log_d_tag,algorithm+"_screKey_Data_Hex:"+dataHex);
                Log.d(log_d_tag,algorithm+"_screKey_Data_Base64:"+dataBase64);
                Log.d(log_d_tag,"===================================密钥=================================================");
                Log.d(log_d_tag,"==================================算法:"+algorithm+"====================================");
                Log.d(log_d_tag,"=====================================HOOK结束===========================================");


            }
        });
        */
        //hook Mac加密算法
        XposedBridge.hookAllMethods(XposedHelpers.findClass("javax.crypto.Mac", loadPackageParam.classLoader),
                "update", new XC_MethodHook() {
                    @Override
                    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                        //Log.e("Stack","Stack",new Throwable("stack dump"));
                        Mac mac = (Mac)param.thisObject;
                        String algorithm = mac.getAlgorithm();
                        byte[] bytes = (byte[]) param.args[0];
                        String data = new String(bytes);
                        String dataHex = Utils.byteToHexString(bytes);
                        String dataBase64 = Base64.encodeToString(bytes,0);
                        Log.d(log_d_tag,"-");
                        Log.d(log_d_tag,"-");
                        Log.d(log_d_tag,"=======================================HOOK开始============================================");
                        Log.d(log_d_tag,"====================================Class_HMAC============================================");
                        Log.d(log_d_tag,algorithm+"_update_Data:"+data);
                        Log.d(log_d_tag,algorithm+"_update_Data_Hex:"+dataHex);
                        Log.d(log_d_tag,algorithm+"_update_Data_Base64:"+dataBase64);
                        Log.d(log_d_tag,"============================算法:"+algorithm+"方法:update==================================");
                        Log.d(log_d_tag,"=====================================HOOK结束==============================================");
                        Log.d(log_d_tag,"=====================================调用堆栈~开始==============================================");
                        Log.d(log_d_tag,Log.getStackTraceString(new Throwable()));
                        Log.d(log_d_tag,"=====================================调用堆栈~结束==============================================");
                    }
                });

        XposedBridge.hookAllMethods(XposedHelpers.findClass("javax.crypto.Mac", loadPackageParam.classLoader),
                "doFinal", new XC_MethodHook() {
                    @Override
                    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                        //Log.e("Stack","Stack",new Throwable("stack dump"));
                        Mac mac = (Mac)param.thisObject;
                        String algorithm = mac.getAlgorithm();
                        if(param.args!=null){
                            if (param.args.length>0) {
                                byte[] bytes = (byte[]) param.args[0];
                                String data = new String(bytes);
                                String dataHex = Utils.byteToHexString(bytes);
                                String dataBase64 = Base64.encodeToString(bytes, 0);
                                Log.d(log_d_tag, "-");
                                Log.d(log_d_tag, "-");
                                Log.d(log_d_tag, "======================================HOOK开始============================================");
                                Log.d(log_d_tag,"====================================Class_HMAC============================================");
                                Log.d(log_d_tag, "--dofinal方法有参数");
                                String parameter_length = param.args.length+"";
                                Log.d(log_d_tag,"parameter_length:"+parameter_length);
                                Log.d(log_d_tag, algorithm + "_doFinal_Data:" + data);
                                Log.d(log_d_tag, algorithm + "_doFinal_Data_Hex:" + dataHex);
                                Log.d(log_d_tag, algorithm + "_doFinal_Data_Base64:" + dataBase64);
                                Log.d(log_d_tag, "============================算法:" + algorithm + "方法:dofinal==============================");
                                Log.d(log_d_tag, "=====================================HOOK结束==============================================");
                            };
                        }

                        byte[] bytes = (byte[]) param.getResult();
                        String dataHex = Utils.byteToHexString(bytes);
                        String dataBase64 = Base64.encodeToString(bytes,0);
                        Log.d(log_d_tag,"-");
                        Log.d(log_d_tag,"-");
                        Log.d(log_d_tag,"=======================================HOOK开始========================================");
                        Log.d(log_d_tag,"=======================================Class_HMAC========================================");
                        Log.d(log_d_tag,"--dofinal方法没有参数");
                        Log.d(log_d_tag,algorithm+"_doFinal_Data_Hex:"+dataHex);
                        Log.d(log_d_tag,algorithm+"_doFinal_Data_Base64:"+dataBase64);
                        Log.d(log_d_tag,"============================算法:"+algorithm+"方法:dofinal==================================");
                        Log.d(log_d_tag,"=====================================HOOK结束==============================================");
                        Log.d(log_d_tag,"=====================================调用堆栈~开始==============================================");
                        Log.d(log_d_tag,Log.getStackTraceString(new Throwable()));
                        Log.d(log_d_tag,"=====================================调用堆栈~结束==============================================");
                    }
                });

    }
}
